package cn.pugle.oj.leetcode;

import cn.pugle.oj.catalog.DesignProblem;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 先写个最呆的, 32 ms
 * <p>
 * 很多坑
 * - getNews里要有自己发的,
 * - 自己follow自己, 要去重...
 * - tweetId不能当做时间
 * - 取消订阅后getNews里就没有那人的
 * - 没follow过就调用unfollow
 *
 * @author tzp
 * @since 2020/11/13
 */
public class LC355_1 implements DesignProblem {
    static class Twitter {
        private static class Tweet {
            public int ts;
            public int user;
            public int tweetId;

            public Tweet(int ts, int user, int tweetId) {
                this.ts = ts;
                this.user = user;
                this.tweetId = tweetId;
            }

            public int getTweetId() {
                return tweetId;
            }
        }

        HashMap<Integer, HashSet<Integer>> fansToStar = new HashMap<>();
        HashMap<Integer, LinkedList<Tweet>> starTweetBox = new HashMap<>();//superStar的话保留在自己的box
        int ts = 0;

        public Twitter() {
        }

        public void postTweet(int userId, int tweetId) {
            Tweet tweet = new Tweet(ts, userId, tweetId);
            starTweetBox.compute(userId, (key, oldValue) -> {
                if (oldValue == null) oldValue = new LinkedList<>();
                oldValue.offerLast(tweet);
                return oldValue;
            });
            ts++;
        }

        public static List<Tweet> last10(List<Tweet> list) {
            if (list == null) return Collections.emptyList();
            if (list.size() >= 10) {
                return list.subList(list.size() - 10, list.size());
            } else {
                return list;
            }
        }

        public List<Integer> getNewsFeed(int userId) {
            LinkedList<Tweet> all = new LinkedList<>(last10(starTweetBox.get(userId)));
            if (fansToStar.containsKey(userId)) {
                for (Integer star : fansToStar.get(userId)) {
                    all.addAll(last10(starTweetBox.get(star)));
                }
            }
            return all.stream()
                    .sorted((o1, o2) -> -Integer.compare(o1.ts, o2.ts))
                    .limit(10)
                    .map(Tweet::getTweetId)
                    .collect(Collectors.toList());
        }

        public void follow(int fans, int star) {
            if (fans == star) return;
            fansToStar.compute(fans, (key, oldValue) -> {
                if (oldValue == null) oldValue = new HashSet<>();
                oldValue.add(star);
                return oldValue;
            });
        }

        public void unfollow(int fans, int star) {//并没有写unfollow之后从super start降级
            if (fans == star) return;
            if (fansToStar.get(fans) != null)
                fansToStar.get(fans).remove(star);
        }
    }

    public static void main(String[] args) {

        //["Twitter","postTweet","getNewsFeed","follow","postTweet","getNewsFeed","unfollow","getNewsFeed"]
        //[[],[1,9],[1],[1,2],[2,6],[1],[1,2],[1]]

        //["Twitter","postTweet","getNewsFeed","follow","postTweet","getNewsFeed","unfollow","getNewsFeed"]
        //[[],[1,5],[1],[1,2],[2,6],[1],[1,2],[1]]

        //["Twitter","postTweet","follow","getNewsFeed"]
        //[[],[1,5],[1,1],[1]]

        //["Twitter","postTweet","postTweet","unfollow","getNewsFeed"]
        //[[],[1,4],[2,5],[1,2],[1]]
        System.out.println(new LC355_1());
    }
}
